
// pages/AIteacher/index.js
const app = getApp()
// 引入封装好的Websocket函数
import chatService from "../../apis/chat.js";
const bg_defalut = '../../assets/chat-bg.png'
const innerAudioContext = wx.createInnerAudioContext({
	useWebAudioImplement: true,
})//音频播放器
Page({

  /**
   * 页面的初始数据
   */
  data: {
    chatId:0,
    //socket相关==============start
    socketTask:null,
    popShow:false,
    heart:false,
    heartbeatfail: 0,
    socketConect: false,
    timeout:10000,
    //socket相关==============end

    replyId:'teacher',
    cardInfo:{},
    chatBg:bg_defalut,
    chatList: [],
    chatNewestId:'1',
    // npc相关
    npcShow:false,
    npc_avatar:'',  // npc头像
    npc_id:'',    
    isFirstInit:true,
    isInput:false, // 用户发送了消息 等待回复

    // 广告
    adIndex:0,
    ads:[
      {
        "message_type": "chat", // chat/npc_action
        "chat_info_list": [ // message_type为chat时传入
            {
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user", // 回复的对象，用户写死teacher
                "type": "text", // 音频+文本类型
                "text_data": {
                    "text": "我有3个ads推荐给你，你可能会对哪个更有兴趣？", // 文本格式数据
                }
            },
            {// 下挂广告选项传入
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user",
                "type": "select", // 选项类型
                "select_data": [
                    {
                        "display_name": "游戏",
                        "value": "1"
                    },
                    {
                        "display_name": "学习",
                        "value": "2"
                    },
                    {
                        "display_name": "女装",
                        "value": "3"
                    },
                    {
                        "display_name": "都行",
                        "value": "4"
                    }
                ]
            }]
      },
      {
        "message_type": "chat", // chat/npc_action
        "chat_info_list": [ // message_type为chat时传入
            {
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user", // 回复的对象，用户写死teacher
                "type": "text", // 音频+文本类型
                "text_data": {
                    "text": "为您推荐", // 文本格式数据
                }
            },
            {// 下挂链接传入
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user",
                "type": "link", // 图片类型
                "link_data": {
                    "url": "https://detail.tmall.com/item.htm?id=733069259166&spm=a21n57.sem.item.2.12213903j9cMDh&priceTId=2150434117331491794891780eec6a&utparam=%7B%22aplus_abtest%22%3A%22fb8062011dfdd87b52da29389a78ac2b%22%7D&&xxc=ad_ztc",
                    "image_url": "../../assets/game.png" ,
                    "display_text": "我系渣渣辉，系兄弟就来砍我" 
                }
            },
        ],
        "timestamp": 1731681433
      },
      {
        "message_type": "chat", // chat/npc_action
        "chat_info_list": [ // message_type为chat时传入
            {
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user", // 回复的对象，用户写死teacher
                "type": "text", // 音频+文本类型
                "text_data": {
                    "text": "为您推荐", // 文本格式数据
                }
            },
            {// 下挂链接传入
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user",
                "type": "link", // 图片类型
                "link_data": {
                    "url": "https://detail.tmall.com/item.htm?id=733069259166&spm=a21n57.sem.item.2.12213903j9cMDh&priceTId=2150434117331491794891780eec6a&utparam=%7B%22aplus_abtest%22%3A%22fb8062011dfdd87b52da29389a78ac2b%22%7D&&xxc=ad_ztc",
                    "image_url": "../../assets/study.png" ,
                    "display_text": "ToTo学英语，你的随身AI老师" 
                }
            },
        ],
        "timestamp": 1731681433
      },
      {
        "message_type": "chat", // chat/npc_action
        "chat_info_list": [ // message_type为chat时传入
            {
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user", // 回复的对象，用户写死teacher
                "type": "text", // 音频+文本类型
                "text_data": {
                    "text": "为您推荐", // 文本格式数据
                }
            },
            {// 下挂链接传入
                "send_from": "teacher", // 发送者：teacher/npc_id等
                "reply_to": "user",
                "type": "link", // 图片类型
                "link_data": {
                    "url": "https://detail.tmall.com/item.htm?id=733069259166&spm=a21n57.sem.item.2.12213903j9cMDh&priceTId=2150434117331491794891780eec6a&utparam=%7B%22aplus_abtest%22%3A%22fb8062011dfdd87b52da29389a78ac2b%22%7D&&xxc=ad_ztc",
                    "image_url": "../../assets/cloth.png" ,
                    "display_text": "汉服服装真丝面料大厂专供" 
                }
            },
        ],
        "timestamp": 1731681433
      }
    ],

    // 语音相关
    duration:0,
    chatPlayId:-1, //当前播放id
    isClick:false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  async onLoad(options) {
    this.getRecordAuthorize()
    this.initInnerAudioContext()
    if (!app.globalData.isLogin) {
        // 显示加载中状态
        this.setData({
            loading: true
        });
        // 监听数据准备好的事件或者定期检查数据是否准备好
        var self = this;
        var checkDataReady = function() {
            if (app.globalData.isLogin) {
              console.log('========initWebSocket========')
              self.initWebSocket()
            } else {
                setTimeout(checkDataReady, 1000);
            }
        };
        checkDataReady();
    } else {
      console.log('========initWebSocket========')
      this.initWebSocket()
    }
  },

  getRecordAuthorize(){
    let _this = this
    wx.getSetting({
      success(res) {
        console.log('getSetting=========',res)
        if (res.authSetting[ 'scope.record']) {
          // wx.showToast({
          //   title: '麦克风权限已启用',
          //   icon:'none'
          // })
        } else {
          wx.authorize({
          scope: 'scope.record',
          success() {
            // 用户已经同意小程序使用录音功能，后续调用 wx.startRecord 接口不会弹窗询问
            wx.showToast({
              title: '麦克风权限已启用',
              icon:'none'
            })
          }
          })
        }
      }
      })
  },
  sendNpcMsg(e){
    console.log('sendMsg==========',e.detail, this.data.replyId)
    const timestamp = Math.floor(Date.now() / 1000);
    let params = {
      "message_type": "chat", // chat
      "chat_info_list": [ // message_type为chat时传入，列表格式，富文本后续拓展用
          {
              "reply_to": this.data.replyId, // 回复的对象，教学智能体写死teacher, 其他npc智能体待定，需要后端发送指令触发唤起，前端暂存
              "type": "text", // 文本类型
              "text_data": {
                  "text": e.detail, // 文本格式数据
              }
          }
      ],
      "timestamp": timestamp,
      id:++this.data.chatId
    }
    this.setData({
      chatList:[...this.data.chatList,params],
    })

    if(this.data.chatList.length>1){
      setTimeout(() => {
        this.setData({
          chatNewestId:'msg' + timestamp
        })
      }, 100);
    }
    let that = this
    this.data.socketTask.send({
      //向服务器发送消息
      data:JSON.stringify(params),
      success: function (res) {
        console.log(res, '发送成功了')
        that.setData({
          isInput:true
        })
      },
      fail: function (err) {
        console.log(err, '发送失败了')
      }
    })
  },
  sendMsg(e){
    console.log('sendMsg==========',e.detail)
    const timestamp = Math.floor(Date.now() / 1000);
    let params = {
      "message_type": "chat", // chat
      "chat_info_list": [ // message_type为chat时传入，列表格式，富文本后续拓展用
          {
              "reply_to": 'teacher', // 回复的对象，教学智能体写死teacher, 其他npc智能体待定，需要后端发送指令触发唤起，前端暂存
              "type": "text", // 文本类型
              "text_data": {
                  "text": e.detail, // 文本格式数据
              }
          }
      ],
      "timestamp": timestamp,
      id:++this.data.chatId
    }
    this.setData({
      chatList:[...this.data.chatList,params],
    })

    if(e.detail == '广告'){
      this.showAds(0)
      return
    }

    if(this.data.chatList.length>1){
      setTimeout(() => {
        this.setData({
          chatNewestId:'msg' + timestamp
        })
      }, 100);
    }
    let that = this
    this.data.socketTask.send({
      //向服务器发送消息
      data:JSON.stringify(params),
      success: function (res) {
        console.log(res, '发送成功了')
        that.setData({
          isInput:true
        })
      },
      fail: function (err) {
        console.log(err, '发送失败了')
      }
    })
  },
  toAds(e){
    this.showAds(e.detail)
  },
  showAds(index){
    const timestamp = Math.floor(Date.now() / 1000);
    let adsContent
    if(index == 4){
      let i = parseInt(2*Math.random()) + 1
      adsContent =JSON.parse(JSON.stringify(this.data.ads[i])) 
    }else{
      adsContent =JSON.parse(JSON.stringify(this.data.ads[index])) 
    }

    console.log('adsContent==============',adsContent)

    adsContent.timestamp = timestamp
    this.setData({
      chatList:[...this.data.chatList,adsContent],
    })
    if(this.data.chatList.length>1){
      setTimeout(() => {
        this.setData({
          chatNewestId:'msg' + timestamp
        })
      }, 100);
    }
  },

  initWebSocket(){
    let that = this
    this.data.socketTask = wx.connectSocket({
      // url: 'wss://tototalk.chat/api/chat/start',
      url: app.globalData.socketUrl,
      header:{
        'content-type': 'application/json',
        'Cookie':wx.getStorageSync('session_id')
      },
      success: async function (res) {
        // console.log('connectSocket=========',that.data.socketTask)
        if(that.data.isFirstInit){
          //只有第一次进入时触发  之后重连不会再触发
          that.setData({
            isFirstInit:false
          })
          let switchRes = await chatService.switch_teaching_plan()
          // console.log('switchRes==========',switchRes)
        }
        that.setData({
          heartbeatfail: 0,
          socketConect: true
        })
      },
      fail: function (err) {
        console.log(err)
      }
    })

    this.data.socketTask.onOpen((res) => {
      that.startHeartBeat(that.data.socketTask)
      // that.data.socketTask.send({
      //   //向服务器发送消息
      //   data:'ping',
      //   success: function (res) {
      //     console.log(res, '发送成功了')
      //   },
      //   fail: function (err) {
      //     console.log(err, '发送失败了')
      //   }
      // })
    })


    this.data.socketTask.onMessage((res) => {
      //监听 WebSocket 接受到服务器的消息事件
      if(res.data == 'ping'){
        return
        //   this.data.socketTask.send({
        //   data: 'pong',
        //   success: function (res) {
        //     console.log(res, '心跳链接')
        //   }
        // })
      }else{
        this.setData({
          isInput:false
        })
        let data = JSON.parse(res.data)
        console.log(data, '服务器的消息')
        if(data.message_type == 'chat'){
          data.id = ++this.data.chatId
          data.isBlurState = true
          this.setData({
            chatList:[...this.data.chatList,data],
          })
          if(this.data.chatList.length>1){
            this.setData({
              chatNewestId:'msg'+ data.timestamp
            })
          }
         
        }
        else if(data.message_type == 'switch_background_image'){
          this.setData({
            chatBg:data.switch_background_image.image_url
          })
        }
        else if(data.message_type == 'npc_action'){
          const {action,npc_id,npc_avatar} = data.npc_action
          if(action == 'begin'){
            //触发npc 出现npc更新npc头像和id
            this.setData({
              npcShow:true,
              npc_avatar,
              replyId:npc_id
            })

            // 插入分割线
            this.setData({
              chatList:[...this.data.chatList,data],
            })

          }else{
            //触发关闭npc 隐藏并将replyid置为teacher
            this.setData({
              npcShow:false,
              replyId:'teacher',
              chatBg:bg_defalut
            })
          }
        }
      }
    })
  },

  startHeartBeat() {
    this.setData({
      heart: true
    })
    this.heartbeat()
  },

  heartbeat() {
    let that = this
    if (!this.data.heart) {
      return
    }
    // let data = {
    //   type: 'heartBeat',
    //   msg: 'this is heatbeat'
    // }
    // console.log('heartbeatfail=========',that.data.heartbeatfail)
    this.data.socketTask.send({
      data: 'ping',
      success: function (res) {
        // console.log(res, '心跳成功,连接正常')
        if (that.data.heart) {
          setTimeout(() => {
            that.heartbeat(that.data.socketTask)
          }, that.data.timeout)
        }
      },
      fail: function (err) {
        that.setData({
          heartbeatfail: that.data.heartbeatfail + 1
        })
        that.data.socketTask.onClose((err) => {
          console.log(err, '关闭的原因')
        })
        // console.log(err, '心跳失败,连接中断')
        if (that.data.heartbeatfail > 2) {
          //大于2次 则重新连接
          that.setData({
            socketTask: [],
            heart:false,
          })
          that.initWebSocket()
        }
        if (that.data.heart) {
          //心跳机制还存在  继续尝试连接
          setTimeout(() => {
            that.heartbeat(that.data.socketTask)
          }, that.data.timeout)
        }
      }
    })
  },

  showPopCard(e){
    chatService.translate_dict(e.detail).then(res=>{
      this.setData({
        popShow:true,
        cardInfo:{
          ...res.data,
          phrase:e.detail
        }
      })
    })
    
  },

  closePop(){
    this.setData({
      popShow:false
    })
  },

  addToWorkbook(e){
    //添加单词到练习册
    chatService.add_practice_record(e.detail).then(res=>{
      this.setData({
        popShow:false
      })
      wx.showToast({
        title: '添加成功',
        icon:'success'
      })
    })
  },
  DelFromWorkbook(e){
    //取消单词到练习册
    chatService.add_practice_record(e.detail,true).then(res=>{
      this.setData({
        popShow:false
      })
      wx.showToast({
        title: '删除成功',
        icon:'success'
      })
    })
  },

  // 语音播放部分
  initInnerAudioContext(){
    innerAudioContext.onPause(()=>{
      console.log('暂停了')
 
    })
    innerAudioContext.onPlay((e)=>{
      // let d = parseInt(innerAudioContext.duration)
      // let cur = this.data.chatList.findIndex(item=>item.id == this.data.chatPlayId)
      // let list = this.data.chatList
      // list[cur].duration = d
      // list[cur].isBlurState = true
      console.log("开始播放了" )
      // this.setData({
      //   chatList:list
      // })
    })
    innerAudioContext.onError(()=>{
      console.log('播放错误')
    })
    innerAudioContext.onEnded(()=>{
      let cur = this.data.chatList.findIndex(item=>item.id == this.data.chatPlayId)
      let list = this.data.chatList
      list[cur].isBlurState = false
      this.setData({
        chatList:list
      })
      console.log('播放完毕',list)

    })
    innerAudioContext.onCanplay(()=>{
        console.log("可以进行播放了",parseInt(innerAudioContext.duration))
        if(this.data.isClick) return
        let d = parseInt(innerAudioContext.duration)
        let cur = this.data.chatList.findIndex(item=>item.id == this.data.chatPlayId)
        let list = this.data.chatList
        list[cur].duration = d
        list[cur].isBlurState = true
        this.setData({
          chatList:list
        })
      }
    )
  },

  playVoice(e){
    console.log('play==============',e.detail)
    const {id, url,isClick} = e.detail
    let cur = this.data.chatList.findIndex(item=>item.id == this.data.chatPlayId)
    let list = this.data.chatList

    this.setData({
      isClick:isClick
    })
    if(cur!==-1){
      list[cur].isBlurState = false
      this.setData({
        chatList:list
      })
      console.log('play=========chatList=====',this.data.chatList)
    }
    // innerAudioContext.stop();
    this.setData({
      chatPlayId:id
    })
    innerAudioContext.src ='data:audio/x-wav;base64,' +  url
    innerAudioContext.play();
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    this.getTabBar().setData({
      active: 0
    })
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
   // 在页面卸载时关闭WebSocket连接
   let that = this
   this.data.socketTask.close({
     success: function (res) {
       console.log(res, '离开页面关闭socket')
      //  that.stopHeartBeat() //离开页面并关闭socket之后停止心跳
     },
     fail: function (err) {
       console.log(err, '关闭socket失败了')
     }
   })
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})